<script setup>
  import * as XLSX from 'xlsx';
  import * as echarts from 'echarts'
  import { watch, ref, reactive, onMounted, nextTick } from 'vue';
  import { useRoute } from 'vue-router';
  import { ElMessage, ElMessageBox } from 'element-plus'
  import {
    GroupIndexes,
    ExtraIndexesData,
    GroupIndexChartOptionStack,
    GroupIndexChartOptionSeason,
    GroupIndexChartOptionInterval,
    UpdateDataIndexReading,
  } from '@/api/datlib/datIndex'
  import { DataPrimaryIndex } from '@/api/datlib/variety'
  import { datetimeToString, dateIntervalDays } from '@/utils/datetimeUtils'
  import useUserInfoStore  from '@/stores/userinfo'
  const userInfoStore = useUserInfoStore()
  const indexBox = ref(null)
  const indexContent = ref(null)
  const indexListTable = ref(null)

  const appRoute = useRoute()
    // 普通图形
  const chartOneBox = ref(null)
  let chartOne = null
  // 季节图形
  const chartTwoBox = ref(null)
  let chartTwo = null
  // 区间图形
  const chartThreeBox = ref(null)
  let chartThree = null

  // 图形的init配置
  const noDataChartOption = {
    graphic: {
      type: 'text',
      left: 'center',
      top: 'middle',
      silent: true,
      style: {
        fill: '#9d9d9d',
        fontWeight: 'bold',
        text: '暂无数据图形',
        fontSize: '17px'
      }
    }
  }
  
  // 当前显示的指标列表
  const currentIndexes = reactive({
    indexList: [],
    selectCount: 0,
    selectIds: [],
    extraDataLoading: false,
  })

  // 查询指标具体数据的配置,图形参数
  const indexParams = reactive({
    dateRange: [],
    currentGroupId: -1,
    currentIndexId: -1,
    currentStackId: [],
    isStack: false,
    stackSeriesType: 'line',
    stackYasisPos: 0,
    chartCurrentDateRange: [],
    hasChartOption: false,
    chartCurrentOption: {}, // 当前图形配置
    statckYears: 3,
    chartStackOption: {},  // 堆叠图形配置
    chartStackLoading: false,
    seasonYears: 3,
    chartSeasonOption: {}, // 季节图形配置
    intervalYears: 3,
    chartIntervalOption: {}, // 区间图形配置
    currentTabName: 'first',
    switchName: '查看数据',
    switchIcon: 'Grid',
    tableCurrentData: [],
    tableCurrentColumns: [],
    tablePage: 1,
    tablePageSize: 50,
    tableStart: 0,
    tableEnd: 50,
    exportLoading: false
  })

  // 指标表格选择变化
  const extraSelectIndexChange = () => {
    const selectIdList = indexListTable.value.getSelectionRows().map((row) => row.id)
    currentIndexes.selectIds = selectIdList
    currentIndexes.selectCount = selectIdList.length
  } 

  // 日期范围快速选择
  const dateRangeShortcuts = [
    {
      text: '本月',
      value: () => {
        const nt = new Date()
        return [datetimeToString(new Date(nt.getFullYear(), nt.getMonth(), 1)), datetimeToString(nt)]
      }
    },
    {
      text: '近六月',
      value: [datetimeToString(dateIntervalDays(new Date(), -180)), datetimeToString(new Date())]
    },
    {
      text: '近一年',
      value: [datetimeToString(dateIntervalDays(new Date(), -360)), datetimeToString(new Date())]
    }
  ]

  // 点击某个具体指标
  const toClickIndexItem = (idx, isHand) => {
    indexParams.currentIndexId = idx.id
    indexParams.currentTabName = 'first'
    if (indexParams.isStack && indexParams.hasChartOption) {
      // console.log('获取数据堆叠图形')
      chartOne.showLoading({ text: '加载中'})
      ExtraIndexesData({
        extra_ids: [indexParams.currentIndexId]
      }).then((res) => { // 设置图形堆叠
        // console.log(res)
        const scolumns = res.data.table_columns
        if (scolumns.length < 1) return
        const scol = scolumns[0]  // 肯定只有一个数据
        const sdata = res.data.table_data
        const curOpt = indexParams.chartStackOption  // 当前的option
        const indexData = {}
        for (let i=0; i<sdata.length; i++) {
          indexData[sdata[i].datadate] = sdata[i].col_0  // 肯定只有一条数据
        }
        const yAxisCount = indexParams.chartStackOption.yAxis.length
        if (indexParams.stackYasisPos === 1 && yAxisCount < 2) {
          curOpt.yAxis.push({ type: 'value', scale: true, name: scol.unit})
        }
        const curXaxis = curOpt.xAxis.data  // 原来的x轴
        curOpt.series.push({
          name: scol.name,
          yAxisIndex: indexParams.stackYasisPos,
          type: indexParams.stackSeriesType,
          symbol: 'none',
          connectNulls: true,
          data: curXaxis.map((xd) => indexData[xd])
        })
        // 设置图形
        indexParams.chartStackOption = JSON.parse(JSON.stringify(curOpt))
        chartOne.setOption(indexParams.chartStackOption, { notMerge: true })
        chartOne.hideLoading()
        currentIndexes.extraDataLoading = false
        // 设置日期范围
        indexParams.dateRange = [scol.start_date, scol.end_date]
      })
    } else {
      // 设置图形配置
      // console.log('设置图形配置')
      chartOne.showLoading({ text: '加载中'})
      GroupIndexChartOptionStack(
        indexParams.currentIndexId,
        indexParams.statckYears
      ).then((res) => {
        // console.log(res)
        indexParams.chartStackOption = res.data.option
        chartOne.setOption(indexParams.chartStackOption, { notMerge: true })
        chartOne.hideLoading()
        indexParams.hasChartOption = true
        // 设置日期范围
        const scol = res.data.data[0]
        indexParams.dateRange = [scol.start_date, scol.end_date]
      })
    }

    getSeasonChartOption() // 季节图形
    getIntervalChartOption() // 区间图形
    if (isHand) {
      UpdateDataIndexReading(idx.id)  // 主动点击的条目，添加访问次数
    }
  }

  // 点击查询按钮，指定日期范围再次主动查询
  const toQueryIndexData = () => {
    // console.log(indexParams.currentIndexId)
    indexParams.isStack = false // 时间段重置，不支持图形叠加
    chartOne.showLoading({ text: '加载中' })
    GroupIndexChartOptionStack(
        indexParams.currentIndexId,
        -1,
        indexParams.dateRange[0],
        indexParams.dateRange[1],
      ).then((res) => {
        // console.log(res)
        indexParams.chartStackOption = res.data.option
        chartOne.setOption(indexParams.chartStackOption, { notMerge: true })
        chartOne.hideLoading()
        indexParams.hasChartOption = true
      })
  }

  // 数据可视化(获取堆叠图形)
  const getStackChartOption = () => {
    indexParams.chartStackLoading = true
    GroupIndexChartOptionStack(
      indexParams.currentStackId.join(','),
      indexParams.statckYears
    ).then((res) => {
      indexParams.chartStackOption = res.data.option
      chartOne.setOption(indexParams.chartStackOption, { notMerge: true })
      indexParams.chartStackLoading = false
      indexParams.hasChartOption = true
    }).catch(() => { indexParams.chartStackLoading = false })
  }
  // 获取季节图形配置
  const getSeasonChartOption = () => {
    chartTwo.showLoading({ text: '加载中' })
    GroupIndexChartOptionSeason(
      indexParams.currentIndexId,
      indexParams.seasonYears
    ).then((res) => {
      const resData = res.data
      indexParams.chartSeasonOption = resData.option
      chartTwo.setOption(indexParams.chartSeasonOption, { notMerge: true })
      chartTwo.hideLoading()
    })
  }
  // 获取区间图形配置
  const getIntervalChartOption = () => {
    chartThree.showLoading({ text: '加载中' })
    GroupIndexChartOptionInterval(
      indexParams.currentIndexId,
      indexParams.intervalYears
    ).then((res) => {
      const resData = res.data
      indexParams.chartIntervalOption = resData.option
      chartThree.setOption(indexParams.chartIntervalOption, { notMerge: true })
      chartThree.hideLoading()
    })
  }
  // 导出当前表格所有数据
  const exportTableToExcel = () => {
    // 重新构建数据,才有中文表头
    indexParams.exportLoading = true
    let excelData = []
    for (let i=0; i< indexParams.tableCurrentData.length; i ++) {
      let row = indexParams.tableCurrentData[i]
      let nrow = {'日期': row['datadate']}
      for (let j=0; j < indexParams.tableCurrentColumns.length; j++) {
        let col = indexParams.tableCurrentColumns[j]
        nrow[col.label] = row[col.prop]
      } 
      excelData.push(nrow)
    }
    let wb = XLSX.utils.book_new()
    let ws = XLSX.utils.json_to_sheet(excelData, { skipHeader: false})
    let timestamp = new Date().getTime()
    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
    XLSX.writeFile(wb, timestamp + '.xlsx')
    indexParams.exportLoading = false
  }

  // 显示数据的表格页码改变
  const tablePageChange = (page) => {
    indexParams.tablePage = page
    indexParams.tableStart = (indexParams.tablePage - 1) * indexParams.tablePageSize
    indexParams.tableEnd = indexParams.tableStart + indexParams.tablePageSize
    // console.log(page, indexParams.tableCurrentData.length, indexParams.tableStart, indexParams.tableEnd)
  }


  // 切换数据与图形显示
  const toggleDataTabView = () => {
    if (indexParams.currentTabName === 'first') {
      indexParams.currentTabName = 'second'
      indexParams.switchName = '查看图形'
      indexParams.switchIcon = 'TrendCharts'
    } else if (indexParams.currentTabName === 'second') {
      indexParams.currentTabName = 'first'
      indexParams.switchName = '查看数据'
      indexParams.switchIcon = 'Grid'
    }
  }
  // 数据可视化
  const indexDataChartView = () => {
    if (currentIndexes.selectIds.length > 3) {
      ElMessage.error('我们建议您可视化小于3个指标图形。')
    }
    if (currentIndexes.selectIds.length > 10) {
      ElMessageBox({
        message: '一次可视化指标过多，请减少至10个以下再尝试!',
        type: 'error',
        title: '错误了'
      })
      return
    }
    indexParams.currentStackId = currentIndexes.selectIds
    indexParams.currentIndexId = currentIndexes.selectIds[0]
    indexParams.currentTabName = 'first'
    // 设置普通图
    getStackChartOption()
    // 设置季节图
    getSeasonChartOption()
    // 设置区间图
    getIntervalChartOption()
  }

  // 提取数据
  const extraIndexData = () => {
    if (currentIndexes.selectIds.length > 10) {
      ElMessageBox({
        message: '一次提取指标过多，请减少至10个以下再尝试!',
        type: 'error',
        title: '错误了'
      })
      return
    }
    indexParams.currentTabName = 'second'
    // 提取数据
    currentIndexes.extraDataLoading = true
    ExtraIndexesData({
      extra_ids: currentIndexes.selectIds
    }).then((res) => {
      // console.log(res)
      indexParams.tableCurrentData = res.data.table_data
      indexParams.tableCurrentColumns = res.data.table_columns
      currentIndexes.extraDataLoading = false
      // console.log(indexParams.tableCurrentData)
    }).catch(() => { currentIndexes.extraDataLoading = false })
  }

  // 设置图形和表格所占视窗的高度
  const setChartAndDataHeight = () => {
    nextTick(() => {
      if (indexBox.value) {
        const indexHeight = indexBox.value.clientHeight
        const docHeight = document.documentElement.clientHeight
        // console.log(indexHeight, docHeight)
        indexContent.value.style.height = (docHeight - indexHeight -126) + 'px'
      }
    })
  }

  watch(()=>appRoute.query.igid, (nid) => {
    // 请求组下的指标数据
    // console.log(`请求id=${nid}组下的指标数据`)
    if (!nid) return
    indexParams.currentGroupId = nid
    // 获取该组下的指标列表
    GroupIndexes(nid).then((res) => {
      const data = res.data.data
      let existIds = []
      for (let i=0; i<currentIndexes.indexList.length; i++) {
        existIds.push(currentIndexes.indexList[i].id)
      }
      let newIndexes = []
      for (let j=0; j< data.length; j++) {
        if (existIds.indexOf(data[j].id) === -1) {
          newIndexes.push(data[j])
        }
      }
      currentIndexes.indexList = [...newIndexes, ...currentIndexes.indexList]
      // 设置图表显示窗高度
      setChartAndDataHeight()
    })
  }, { immediate: true })

  watch(() => appRoute.query.vcode, (ncode) => {
    if (!ncode || indexParams.isStack) return
    // 若未渲染图形，就渲染主要图
    // if (!indexParams.hasChartOption) {
    //   console.log('需要渲染主图')
    // }
    DataPrimaryIndex(ncode).then((res) => {
      const index = res.data.data
      if (index) {
        toClickIndexItem(index)
      }
    })
  }, { immediate: true })

  onMounted(() => {
    chartOne = echarts.init(chartOneBox.value) // [指定图形渲染的dom]
    chartTwo = echarts.init(chartTwoBox.value) // [季节图形渲染的dom]
    chartThree = echarts.init(chartThreeBox.value) // [区间图形]
    chartOne.setOption(noDataChartOption)
    chartTwo.setOption(noDataChartOption)
    chartThree.setOption(noDataChartOption)
  })
</script>
<template>
  <div class="page-view">
    <!-- 指标栏 -->
    <div ref="indexBox" class="index-box">
      <el-table
        ref="indexListTable"
        max-height="272"
        row-class-name="table-row"
        empty-text="该组别下暂无数据指标"
        :data="currentIndexes.indexList"
        @selection-change="extraSelectIndexChange"
      >
        <el-table-column type="selection" width="25" />
        <el-table-column label="指标名称">
          <template #default="scope">
            <div class="index-name" @click="toClickIndexItem(scope.row, true)">
              {{ scope.row.name }}
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 操作按钮条 -->
    <div class="data-actions">
      <el-button
        plain
        :disabled="currentIndexes.selectIds.length<1"
        :loading="indexParams.chartStackLoading"
        @click="indexDataChartView"
      >
        数据可视化<span v-if="currentIndexes.selectCount > 0">({{ currentIndexes.selectCount }})</span>
      </el-button>
      <el-button
        plain
        :disabled="currentIndexes.selectIds.length<1"
        :loading="currentIndexes.extraDataLoading"
        @click="extraIndexData"
      >
        提取数据<span v-if="currentIndexes.selectCount > 0">({{ currentIndexes.selectCount }})</span>
      </el-button>
      <el-button
        plain
        :icon="indexParams.switchIcon"
        @click="toggleDataTabView"
      >
        {{ indexParams.switchName }}
      </el-button>
      <el-button
        v-if="userInfoStore.isVip"
        plain
        type="primary"
        :loading="indexParams.exportLoading"
        :disabled="indexParams.currentTabName !== 'second'"
        icon="Download"
        @click="exportTableToExcel"
      >
        导出数据
      </el-button>
      <el-button
        plain
        icon="Delete"
        @click="currentIndexes.indexList = []"
      >
        清空指标
      </el-button>
    </div>
    <!-- 图表数据窗 -->
    <div ref="indexContent" class="index-content">
      <el-scrollbar>
        <el-tabs
          v-model="indexParams.currentTabName"
        >
          <el-tab-pane label="图形" name="first">
            <div class="param-box">
              <el-space>
                <el-date-picker
                  v-model="indexParams.dateRange"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  value-format="YYYY-MM-DD"
                  style="width: 220px"
                  :shortcuts="dateRangeShortcuts"
                  :unlink-panels="true"
                  :clearable="false"                
                />
                <el-button type="primary" @click="toQueryIndexData">查询</el-button>
                <el-tooltip
                  content="勾选后再次点击的指标数据将在图形上叠加可视化"
                  placement="bottom-start"
                >
                  <el-checkbox v-model="indexParams.isStack">图形叠加</el-checkbox>
                </el-tooltip>
                <div v-show="indexParams.isStack" class="stack-box">
                  <span>指标数据以</span>
                  <span>
                    <el-select
                      v-model="indexParams.stackSeriesType"
                      class="stack-select"
                      style="width: 80px;"
                    >
                      <el-option value="line" label="折线图" />
                      <el-option value="bar" label="柱形图" />
                    </el-select>
                  </span>
                  <span>叠加于</span>
                  <span>
                    <el-select
                      v-model="indexParams.stackYasisPos"
                      class="stack-select"
                      style="width: 80px"
                    >
                      <el-option :value="0" label="左轴" />
                      <el-option :value="1" label="右轴" />
                    </el-select>
                  </span>
                </div>
              </el-space>
            </div>
            <div class="charts-list">
              <div ref="chartOneBox" class="chart-box"></div>
              <div ref="chartTwoBox" class="chart-box"></div>
              <div ref="chartThreeBox" class="chart-box-row-cross"></div>
            </div>
          </el-tab-pane>
          <el-tab-pane label="数据" name="second">
            <el-table
              stripe 
              :data="indexParams.tableCurrentData.slice(indexParams.tableStart, indexParams.tableEnd)"
            >
              <el-table-column prop="datadate" label="日期" width="100">
                <template #header>
                  <div>
                    <div>日期</div>
                    <div>单位</div>
                  </div>
                </template>
              </el-table-column>
              <el-table-column 
                v-for="col in indexParams.tableCurrentColumns" 
                :key="col.prop"
                :prop="col.prop"
                :label="col.label"
              >
              <template #header>
                <div>
                  <div>{{ col.label }}</div>
                  <div>{{ col.unit }}</div>
                </div>
              </template>
              </el-table-column>
            </el-table>
            <div class="table-option">
              <div>
                <el-pagination
                  small
                  background
                  hide-on-single-page
                  layout="prev, pager, next"
                  :page-size="indexParams.tablePageSize"
                  :total="indexParams.tableCurrentData.length"
                  @current-change="tablePageChange"
                />
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-scrollbar>
    </div>
  </div>
</template>
<style scoped lang="scss">
  .page-view {
    .index-box {
      // width: 1117px;
      // border-top: 1px solid #ebeef5;
      // border-bottom: 1px solid #ebeef5;
      // padding: 8px 0px;
      font-size: 14px;
      max-height: 500px;
      min-height: 120px;
      overflow-y: auto;
      // background-color: #dce5f8;
      .index-name {
        cursor: pointer;
        font-size: 14px;
        &:hover {
          color: $goldenColor;
        }
      }
      .el-table ::v-deep(.table-row) {
        font-size: 13px;
        color: #222;
      }
    }
    .data-actions {
      height: 30px;
      display: flex;
      align-items: center;
      padding-left: 10px;
      background: linear-gradient(to bottom,#eee,#fff, #eee);
      .data-actions-right{
        margin-left: auto;
      }
      ::v-deep(.el-button) {
        margin-left: 0;
        padding: 5px 7px;
        border:none;
        color: #222;
        background-color: rgba(238, 238, 200, 0);
        &:focus-visible {
          outline: 0;
        }
        &:hover {
          color: $goldenColor;
        }
      }
    }

    .index-content {
      .el-tabs ::v-deep(.el-tabs__header) {
        display:none;
      }
      .param-box {
        display: flex;
        align-items: center;
        margin-top: 6px;
        padding-left: 8px;
        .stack-box {
          font-size: 14px;
          user-select: none;
          .stack-select {
            ::v-deep(.el-input__wrapper){
              border-radius: 0;
              box-shadow: 0 0 0 0 !important;
              &:hover {
                box-shadow: 0 0 0 0;
              }
            }
          }
        } 
      }
      .charts-list {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        margin-top: 16px;
        .chart-box {
          // box-shadow: 0px 0px 4px #eee;
          border-top: 1px solid #efefef;
          border-bottom: 1px solid #efefef;
          margin-left: 8px;
          margin-bottom: 16px;
          width: 548px;
          height: 333px;
        }
        .chart-box-row-cross {
          border-top: 1px solid #efefef;
          border-bottom: 1px solid #efefef;
          margin-top: 16px;
          margin-left: 8px;
          margin-bottom: 16px;
          width: 1105px;
          height: 500px;
        }
      }
      
      .table-option {
        margin: 16px 0;
        display: flex;
        align-items: center;
      }
    }
  }
</style>